/*
 * AcceptMessageHandler.java
 *
 * Created on 29 februari 2008, 14:15
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package client.communication;

import client.controllers.BoggleController;
import client.gui.Login;
import client.gui.CreateGameroom;
import client.gui.Chatroom;
import client.gui.controls.scrabble.Blokje;
import client.gui.BoggleClient;
import client.gui.controls.scrabble.Plankje;
import client.gui.ScrabbleClient;
import client.controllers.ScrabbleController;
import client.gui.SpelbordScrabble;
import client.gui.Topscores;
import java.awt.Color;
import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.logging.Level;
import org.apache.log4j.Logger;
import org.xml.sax.InputSource;
import data.Gameroom;
import data.Gebruiker;
import data.SpelScore;
import java.io.ObjectInputStream;
import javax.swing.ImageIcon;
import javax.swing.JFrame;

/**
 * Klasse die de communicatie tussen de server en een client verzorgt.
 * De communicatie verloopt over een netwerk dus wordt door middel van
 * sockets verwezenlijkt. 
 */
public class ClientCommunication {

    private Logger logger = Logger.getLogger(ClientCommunication.class);
    private InetAddress host;
    private int port;
    private Socket link = null;
    private BufferedReader in;
    private PrintWriter out;
    private Chatroom chatroom;
    private Login frmInlog;
    private CreateGameroom frmCreateGameroom;
    private SpelbordScrabble spelbord;
    private ScrabbleClient scrabbleClient;
    private Topscores topscoreGui;
    AcceptMessageHandler listener;
    private Thread t;
    //CSAXParserClient
    private CSAXParserClient parser;
    private final static ClientCommunication instance = new ClientCommunication();
    private Plankje plankje;
    private boolean aanDeBeurt; //dit moet op false gezet worden tijdelijk enkel op true gezet om project nog te kunnen runnen
    private Hashtable<String, Integer> letterWaardes;
    private Hashtable<String, String> smilies;
    private BoggleClient boggleclient;

    public void setBoggleClient(BoggleClient boggleclient) {
        this.boggleclient = boggleclient;
    }

    public void setLetterWaardes(Hashtable<String, Integer> letterWaardes) {
        this.letterWaardes = letterWaardes;
    }

    public Hashtable<String, Integer> getLetterWaardes() {
        return this.letterWaardes;
    }

    public boolean isAanDeBeurt() {
        return aanDeBeurt;
    }
    private String gameNaam;

    public String getGameNaam() {
        return gameNaam;
    }

    public void setAanDeBeurt(boolean aanDeBeurt) {
        this.aanDeBeurt = aanDeBeurt;
        if (getScrabbleClient() != null) {
            getScrabbleClient().enableKnoppen(aanDeBeurt);
            if (aanDeBeurt) {
                getScrabbleClient().startTimer();
            } else {
                getScrabbleClient().stopTimer();
            }
        }
    }

    public Plankje getPlankje() {
        return plankje;
    }

    /** 
     * Class constructor (Default)
     */
    private ClientCommunication() {
        parser = new CSAXParserClient();
        setAanDeBeurt(false);
    }

    public static ClientCommunication getInstance() {
        return instance;
    }

    /**
     * Functie die de connectie met de server maakt. Hiervoor is een ip en een 
     * poort nodig waarmee de connectie kan gemaakt worden.
     * @param ip Adres van de server waarmee men connectie wil maken.
     * @param port Poort waarop de server connecties toelaat
     */
    public boolean makeConnection(String ip, int port) {
        try {
            if (link == null) {
                logger.info("Making connection with IP " + ip + " and port " + port + "...");
                host = InetAddress.getByName(ip);
                this.port = port;
                //1: connectie maken
                link = new Socket(host, port);

                //2: input & outputkanaal instellen
                in = new BufferedReader(new InputStreamReader(link.getInputStream()));
                out = new PrintWriter(link.getOutputStream(), true);

                listener = new AcceptMessageHandler();
                t = new Thread(listener);
                t.start();
            }

            return true;
        } catch (IOException ioe) {
            //Fout wanneer het ip of poortnummer verkeerd is
            logger.error("Verbinding maken met de server mislukt!");
            logger.error(ioe.getMessage());
            getFrmInlog().foutboodschap("Verbinding maken met de server mislukt.\nGelieve het IP-adres van de server te controleren!");
            return false;
        }
    }

    //sluiten communicatie
    /**
     * Functie die instaat voor het afsluiten van de connectie
     * @throws java.io.IOException Exceptie die wordt opgeworpen indien er
     *                             een fout ontstond bij het afsluiten van
     *                             de connectie.
     */
    public void closeConnection() throws IOException {
        if (link != null && link.isConnected()) {
            out.println("CLOSE");
            out.close();
            in.close();
            link.close();
        }
    }

    /**
     * Functie
     * @param login De loginnaam van de gebruiker
     * @param password Het paswoord van de gebruiker
     * @throws java.io.IOException Exceptie in geval van fout
     */
    public void getSpelerByLogin(String login, String password) throws IOException {
        out.println("<?xml version=\"1.0\"?><getSpelerByLogin><nickname>" + login + "</nickname><password>" + password + "</password></getSpelerByLogin>");
    }

    public void getSpelerByNickname(String login) throws IOException {
        logger.info("saanvraag string wordt verstuurd.");
        out.println("<?xml version=\"1.0\"?><getSpelerByNickname><nickname>" + login + "</nickname></getSpelerByNickname>");
    }

    public void getRandomWoord() {
        out.println("<?xml version=\"1.0\"?><getRandomWoord></getRandomWoord>");
    }

    //checken of een speler al ingelogd is
    /**
     * Functie die nagaat of de speler al online is. Een speler kan geen 
     * twee keer inloggen.
     * @param login loginnaam van de gebruiker.
     */
    public void spelerAlOnline(String login) {
        out.println("<?xml version=\"1.0\"?><spelerAlOnline><nickname>" + login + "</nickname></spelerAlOnline>");

    }

    
    /**
     * Functie die de gegevens van een speler update.
     * @param g Gebruiker 
     * @throws java.io.IOException Exceptie in geval van fout.
     * @throws java.lang.ClassNotFoundException Exceptie in geval van fout
     */
    public void updateSpeler(Gebruiker g) throws IOException, ClassNotFoundException {
        logger.debug("de gebruiker met naam " + g.getNickname() + " wordt nu naar de server doorgestuurd om te updaten.");
        out.println("<?xml version=\"1.0\"?><updateGebruiker>" + g.convertToXML() + "</updateGebruiker>");
    }

    /**
     * Functie die een nieuwe speler aanmeld.
     * @param login loginnaam van de gebruiker.
     */
    public void spelerOnline(String login) {
        out.println("<?xml version=\"1.0\"?><spelerOnline><nickname>" + login + "</nickname></spelerOnline>");
    }

    public void verhoogBoggleScore(int scoreId,int score) {
        out.println("<?xml version=\"1.0\"?><verhoogBoggleScore><scoreid>"+scoreId+"</scoreid><score>"+score+"</score></verhoogBoggleScore>");
    }

    public void verhoogBoggleVerlorenScore(int scoreId, int score) {
        out.println("<?xml version=\"1.0\"?><verhoogVerlorenBoggleScore><scoreid>"+scoreId+"</scoreid><score>"+score+"</score></verhoogBoggleScore>");out.println("<?xml version=\"1.0\"?><verhoogBoggleScore><scoreid>"+scoreId+"</scoreid><score>"+score+"</score></verhoogVerlorenBoggleScore>");
    }
    
    public void verhoogGalgjeScore(int scoreId) {
        out.println("<?xml version=\"1.0\"?><verhoogGalgjeScore><scoreid>"+scoreId+"</scoreid></verhoogGalgjeScore>");
    }

    public void verlaagGalgjeScore(int scoreId) {
        out.println("<?xml version=\"1.0\"?><verhoogGalgjeVerlorenScore><scoreid>"+scoreId+"</scoreid></verhoogGalgjeVerlorenScore>");
    }

    public void zendChatBericht(String afzender, String bericht) {
        out.println("<?xml version=\"1.0\"?><chat><nickname>" + afzender + "</nickname><bericht>" + bericht + "</bericht></chat>");
    }

    /**
     * Functie die aangeeft dat een gebruiker met naam login offline gaat
     * @param login Loginnaam van de gebruiker
     */
    public void spelerOffline(String login) {
        out.println("<?xml version=\"1.0\"?><spelerOffline><nickname>" + login + "</nickname></spelerOffline>");
    }

    public void zendPriveChatBericht(String afzender, String bericht, String ontvanger) {
        out.println("<?xml version=\"1.0\"?><priveChat><nickname>" + afzender + "</nickname><bericht>" + bericht + "</bericht><ontvanger>" + ontvanger + "</ontvanger></priveChat>");
    }

    /**
     * 
     */
    public void onlineSpelers() {
        out.println("<?xml version=\"1.0\"?><onlineSpelers></onlineSpelers>");
    }

    public void haalGameroomsOp() {
        out.println("<?xml version=\"1.0\"?><getGamerooms></getGamerooms>");
    }

    public void geefBeurtDoor() {
        this.setAanDeBeurt(false);
        out.println("<?xml version=\"1.0\"?><geefBeurtDoor>" + gameNaam + "</geefBeurtDoor>");
    }

    /**
     * Functie die een nieuwe speelkamer aanmaakt
     * @param login Loginnaam van de gebruiker
     */
    public void createGameroom(Gameroom gr) {
        String lijn = "<?xml version=\"1.0\"?><createGame>";
        lijn += gr.convertToXML();
        lijn += "</createGame>";
        out.println(lijn);
        gameNaam = gr.getGamenaam();
    //setAanDeBeurt(true);
    }

    public void joinGameroom(String nickname, String roomName) {
        out.println("<?xml version=\"1.0\"?><joinGame><gameNaam>" + roomName + "</gameNaam><nickname>" + nickname + "</nickname></joinGame>");
        gameNaam = roomName;
        setAanDeBeurt(false);
    }

    public void leaveGame(String nickname, String gameNaam) {
        out.println("<?xml version=\"1.0\"?><leaveGame><gameNaam>" + gameNaam + "</gameNaam><nickname>" + nickname + "</nickname></leaveGame>");
        setAanDeBeurt(false);
        gameNaam = null;
    }

    public void zendInGameChatBericht(String nickname, String roomName, String bericht) {
        out.println("<?xml version=\"1.0\"?><chatInGame><bericht>" + bericht + "</bericht><gameNaam>" + roomName + "</gameNaam><nickname>" + nickname + "</nickname></chatInGame>");
    }

    public void zendGelegdeWoorden(String nickname, String roomName, ArrayList<String> woorden, int score) {

        if (woorden != null) {
            //logger.info(" zendGelegdeWoorden: "+woorden.size());
            String lijn = "<?xml version=\"1.0\"?><gelegdeWoorden><nickname>" + nickname + "</nickname>";
            lijn += "<gameNaam>" + roomName + "</gameNaam><score>" + score + "</score><woordenLijst>";
            for (String sWoord : woorden) {
                lijn += "<nieuwWoord>" + sWoord + "</nieuwWoord>";
            }
            lijn += "</woordenLijst></gelegdeWoorden>";
            out.println(lijn);
        }
    }

    public void verplaatsBlokjeOpSpelbord(Point positie, Point oudePositie, String letter, boolean blanco, String gameNaam) {

        String lijn = "<?xml version=\"1.0\"?><verplaatsBlokje>";
        if (positie == null) {
            lijn += "<x>-1</x><y>-1</y>";//wanneer het blokje terug op het plankje gelegd is
        } else {
            lijn += "<x>" + positie.x + "</x><y>" + positie.y + "</y>";
        }
        if (oudePositie == null) {
            lijn += "<xOud>-1</xOud><yOud>-1</yOud>";//wanner het blokje van het plankje komt
        } else {
            lijn += "<xOud>" + oudePositie.x + "</xOud><yOud>" + oudePositie.y + "</yOud>";
        }
        lijn += "<letter>" + letter + "</letter><blanco>" + blanco + "</blanco><gameNaam>" + gameNaam + "</gameNaam></verplaatsBlokje>";
        out.println(lijn);
    }

    public void aanvraagLetters(int aantal, String nickname, String gameNaam) {
        //ArrayList<String> tab = new ArrayList<String>();
        out.println("<aanvraagLetters><aantalLetters>" + aantal + "</aantalLetters><nickname>" + nickname + "</nickname><gameNaam>" + gameNaam + "</gameNaam></aanvraagLetters>");
    //return tab;
    }

    public void geefOverblijvendeLettersTerug(ArrayList<String> letters, String nickname) {
        String lijn = "<?xml version=\"1.0\"?><geefOverblijvendeLettersTerug><letters>";
        for (int i = 0; i < letters.size(); i++) {
            lijn += "<letter>" + letters.get(i) + "</letter>";
        }
        lijn += "</letters><gameNaam>" + gameNaam + "</gameNaam><nickname>" + nickname + "</nickname></geefOverblijvendeLettersTerug>";
        out.println(lijn);
    }

    public void geefLettersTerug(ArrayList<String> letters) {
        String lijn = "<?xml version=\"1.0\"?><geefLettersTerug><letters>";
        for (int i = 0; i < letters.size(); i++) {
            lijn += "<letter>" + letters.get(i) + "</letter>";
        }
        lijn += "</letters><gameNaam>" + gameNaam + "</gameNaam></geefLettersTerug>";
        out.println(lijn);
    }

    public void startSpel(String gameName) {
        out.println("<?xml version=\"1.0\"?><startSpel><gameNaam>" + gameName + "</gameNaam></startSpel>");
    }

    public void pasBeurt(String nickname, String gameName) {
        this.setAanDeBeurt(false);
        out.println("<?xml version=\"1.0\"?><pasBeurt><gameNaam>" + gameName + "</gameNaam><nickname>" + nickname + "</nickname></pasBeurt>");
    }

    public void beurtVerlopen(String nickname, String gameName) {
        out.println("<?xml version=\"1.0\"?><beurtVerlopen><gameNaam>" + gameName + "</gameNaam><nickname>" + nickname + "</nickname></beurtVerlopen>");
        this.geefBeurtDoor();
    }

    /**
     * Functie die de Chatroom van de gebruiker terug geeft
     * @return Chatroom van gebruiker
     */
    public Chatroom getChatroom() {
        return chatroom;
    }

    /**
     * Functie die de Chatroom van de gebruiker instelt
     * @param frmOpstart Chatroom van de gebruiker
     */
    public void setChatroom(Chatroom room) {
        this.chatroom = room;
    }

    public void setPlankje(Plankje p) {
        this.plankje = p;
    }

    /**
     * Functie die het Login frame van de gebruiker weergeeft.
     * @return Loginframe
     */
    public Login getFrmInlog() {
        return frmInlog;
    }

    /**
     * Functie die het Login frame van de gebruiker instelt.
     * @param frmInlog Login frame
     */
    public void setFrmInlog(Login frmInlog) {
        this.frmInlog = frmInlog;
    }

    public SpelbordScrabble getSpelbord() {
        return spelbord;
    }

    public void setSpelbord(SpelbordScrabble spelbord) {
        this.spelbord = spelbord;
    }

    public void bepaalTopscores(Gameroom.Gametype type, String nickname) {
        out.println("<?xml version=\"1.0\"?><bepaalTopscore><spelType>" + type.toString().toLowerCase() + "</spelType>" +
                "<nickname>" + nickname +
                "</nickname></bepaalTopscore>");
    }

    //---------------- Methodes aangeroepen door de XML Handler ----------------
    public void verderInloggen(boolean bool) {
        getFrmInlog().inloggen(bool);
    }

    public void bestaatSpeler(Gebruiker g) {
        //teruggekregen gebruiker object instellen
        getFrmInlog().setGebruiker(g);
        //het inloggen laten verder gaan
        getFrmInlog().verderInloggen();
    }

    public void replySpelerOnline(String nickname) {
        onlineSpelers();
        getChatroom().plaatsBericht(">> " + nickname + " is online");
    }

    public void replySpelerOffline(String nickname) {
        onlineSpelers();
        getChatroom().plaatsBericht(">> " + nickname + " is offline");
    }

    public void onlineSpelersOpvullen(ArrayList<Gebruiker> spelers) {
        getChatroom().setSpelers(spelers);
        getChatroom().opvullenOnlineSpelers();
    }

    public void plaatsChatBerichtOpScherm(String afzender, String bericht) {
        getChatroom().plaatsBericht(afzender + ">> " + bericht);
    }

    public void gameroomAangemaakt(boolean aangemaakt, data.Gameroom.Gametype type) {
        getFrmCreateGameroom().gameroomAangemaakt(aangemaakt, type);
    }

    public void gameroomToegevoegd(Gameroom gr) {
        getChatroom().gameroomToevoegen(gr);
    }

    public void vulGameroomsOp(ArrayList<Gameroom> gamerooms) {
        getChatroom().vulGameroomsOp(gamerooms);
    }

    public void replyChatInGame(String nickname, String bericht) {
        if (getChatroom().getScrabbleGame() != null) {
            getChatroom().getScrabbleGame().toonBerichtInChatVenster(">> " + nickname + " says: " + bericht, false);
        } else if (getChatroom().getBogglegame() != null) {
            getChatroom().getBogglegame().toonBerichtInChatVenster(">> " + nickname + " says: " + bericht, false);
        }
    }

    public void replySpelerJoined(String nickname) {
        if (getChatroom().getScrabbleGame() != null) {
            getChatroom().getScrabbleGame().showMessage(">> Speler " + nickname + " is toegevoegd aan dit spel.", Color.BLACK);
        }
        if (getChatroom().getBogglegame() != null) {
            getChatroom().getBogglegame().toonBerichtInChatVenster(">> Speler " + nickname + " is toegevoegd aan dit spel.", true);
        }
    }

    public void replyLeaveGame(String nickname) {
        if (getChatroom().getScrabbleGame() != null) {
            getChatroom().getScrabbleGame().showMessage(">> Speler " + nickname + " heeft dit spel verlaten!", Color.BLACK);
        } else if (getChatroom().getBogglegame() != null) {
            getChatroom().getBogglegame().toonBerichtInChatVenster(">> Speler " + nickname + " heeft dit spel verlaten!", true);
        }
    }

    public void updateScoreLijst(Hashtable<String, Integer> scores) {
        if (getChatroom().getScrabbleGame() != null) {
            getChatroom().getScrabbleGame().updateScoreLijst(scores);
        } else if (getChatroom().getBogglegame() != null) {
            getChatroom().getBogglegame().updateScoreLijst(scores);
        }
    }

    public void replyToAllSpelerInGame(String nickname) {
        getChatroom().plaatsBericht(">> Speler " + nickname + " is een spel begonnen.");
    }

    public void printAantalBlokjesResterendInZakje(int aantal) {
        if (getScrabbleClient() != null) {
            getScrabbleClient().printAantalBlokjesInZakje(aantal);
        }
    }

    public void plaatsBlokjesOpPlankje(ArrayList<String> nieuweLetters) {
        //Blokjes op het plankje plaatsen
        ArrayList<Blokje> nieuweBlokjes = new ArrayList<Blokje>();
        for (String chr : nieuweLetters) {
            Blokje b = new Blokje(chr);
            b.setWaarde(getLetterWaardes().get(chr).intValue());
            if (chr.equals("?")) {
                b.setBlancoBlokje(true);
            }
            nieuweBlokjes.add(b);
        }

        ArrayList<String> overbodigeBlokjes = getPlankje().plaatsBlokjes(nieuweBlokjes);
        if (overbodigeBlokjes.size() > 0) {
            //Blokjes die teveel zijn terug in het zakje met nog te verdelen
            //blokjes steken dat langs serverkant staat
            geefLettersTerug(overbodigeBlokjes);
        }
    }

    public void replyMaxBeurtVerlopen(String nickname) {
        if (scrabbleClient != null) {
            if (scrabbleClient.getGebruiker().getNickname().equals(nickname)) {
                //De speler die dit bericht ontvangt moet verwijderd worden uit het spel
                //=> alles disabled zetten behalve chatten
                scrabbleClient.enableKnoppen(false);
                scrabbleClient.disableChatten();
                scrabbleClient.showMessage(">> U heeft uw tijd te vaak laten verlopen. Gelieve het spel af te sluiten.", Color.RED);
            } else {
                scrabbleClient.toonBerichtInChatVenster(">> Speler " + nickname + " werd uit het spel verwijderd omdat hij niet meer meespeelde!", true);
            }
        }
    }

    public void replySpelGestart() {
        if(getChatroom().getScrabbleGame() != null){
            getChatroom().getScrabbleGame().setSpelGestart(true);
            getChatroom().getScrabbleGame().enableKnoppen(aanDeBeurt);
            getChatroom().getScrabbleGame().vraagBlokjesAan(getPlankje().getMaxAantalBlokjes(), getChatroom().getScrabbleGame().getGebruiker().getNickname(), getGameNaam());
            getChatroom().getScrabbleGame().showMessage(">> Het spel is gestart! Uw blokjes worden opgehaald...", Color.BLACK);
        }else if(getChatroom().getBogglegame() != null){
            logger.info("boggle game != null");
            getChatroom().getBogglegame().setSpelGestart(true);
            getChatroom().getBogglegame().startTimer();
            getChatroom().getBogglegame().vulBordOp();
            getChatroom().getBogglegame().showMessage(">> Het spel is gestart!", Color.BLACK);
        }
        
    }

    public void replySpelAfgelopen() {
        //Spel stoppen en resterende blokjes teruggeven om score te berekenen
        ArrayList<String> letters = new ArrayList<String>();
        for (int i = 0; i < plankje.getAantalBlokjes(); i++) {
            letters.add(plankje.getBlokjes()[i].getLetter());
        }

        geefOverblijvendeLettersTerug(letters, scrabbleClient.getGebruiker().getNickname());
    }

    public void replyToonWinnaars(ArrayList<String> winnaars) {
        if (winnaars.size() == 1) {
            getChatroom().getScrabbleGame().showMessage(">> " + winnaars.get(0) + " heeft dit spelletje gewonnen!", Color.BLACK);
        } else if (winnaars.size() > 1) {
            getChatroom().getScrabbleGame().showMessage(">> Gelijkspel!", Color.BLACK);
        }
    }

    public CreateGameroom getFrmCreateGameroom() {
        return frmCreateGameroom;
    }

    public void setFrmCreateGameroom(CreateGameroom frmCreateGameroom) {
        this.frmCreateGameroom = frmCreateGameroom;
    }

    public void RegistreerGebruiker(Gebruiker g) {
        out.println("<?xml version=\"1.0\"?><registreerGebruiker>" + g.convertToXML() + "</registreerGebruiker>");
    }

    public void woordafhandeling(ArrayList<String> arlWoorden) {
        logger.info("aantal woorden in woordafhandeling: " + arlWoorden.size());
        if (arlWoorden.size() == 0) //en de beurt was aan jou 
        {
            //beurt in orde en beurt doorgeven
            //en blokjes vastleggen
            if (aanDeBeurt) {

                logger.info("Je was aan de beurt en al je woorden waren juist.");
                ScrabbleController.getInstance().setBlokjesGevalideerd();
                //plankje.plaatsBlokjes(BlokjesVerdeler.getInstance().geefblokjes(7));
                //setAanDeBeurt(false);
                geefBeurtDoor();

            } else {
                ScrabbleController.getInstance().setBlokjesGevalideerd();
                logger.info("het was niet jouw beurt");
            // de letters van de andere spelers moeten ook worden vastgelegd
            }
            ScrabbleController.getInstance().setEersteWoord(false);

        } else if (aanDeBeurt) //beurt aan jou
        {
            //er werden woorden gevonden die niet in de woordenlijst staan 
            //hiervoor zal later een funcite voor aanvragen van juiste woorden voorzien worden
            //nu verwijderd iedereen gewoon blokjes van spelbord
            String lijn;
            if (arlWoorden.size() > 1) {
                lijn = ">> Volgende woorden werden niet teruggevonden in de database: " + arlWoorden.get(0);
                for (int i = 1; i < arlWoorden.size(); i++) {
                    lijn += " " + arlWoorden.get(i);
                }
                lijn += ".";
            } else {
                lijn = ">> Volgend woord werd niet teruggevonden in de database: " + arlWoorden.get(0) + ".";
            }
            getScrabbleClient().showMessage(lijn, Color.red);
            ScrabbleController.getInstance().removeNietGevalideerdeBlokjes();
        }


    }

    public void replyVerplaatsBlokje(Point p, Point oudePositie, String letter, boolean blanco) {
        getSpelbord().plaatsBlokjeOpSpelbord(p, oudePositie, letter, blanco);
    }

    public ScrabbleClient getScrabbleClient() {
        return scrabbleClient;
    }

    public void setScrabbleClient(ScrabbleClient scrabbleClient) {
        this.scrabbleClient = scrabbleClient;
    }

    public void ReplyToAllSpelerAanDeBeurt(String nickname) {
        getChatroom().getScrabbleGame().showMessage(">> Speler " + nickname + " is nu aan de beurt.", Color.BLACK);
    }

    public void checkNicknameBestaatAl(String nickname) {
        out.println("<?xml version=\"1.0\"?><checkNicknameBestaatAl><nickname>" + nickname + "</nickname></checkNicknameBestaatAl>");
    }

    public void geefAvatarAanvraag(String nickname) {
        out.println("<?xml version=\"1.0\"?><geefAvatarAanvraag><nickname>" + nickname + "</nickname></geefAvatarAanvraag>");
    }

    public void startAvatarSocket(int poort) {
        try {
            Socket Avatarlink = new Socket(host, poort);
            ObjectOutputStream out = new ObjectOutputStream(Avatarlink.getOutputStream());
            out.writeObject(this.frmInlog.getRfrm().getImg());
            out.flush();
            out.close();
            Avatarlink.close();

        } catch (IOException ex) {
            logger.info(ex);
        }
    }

    public void startGeefAvatarSocket(int poort) {
        try {
            Socket link = new Socket(host, poort);
            ObjectInputStream objin = new ObjectInputStream(link.getInputStream());
            ImageIcon icon = (ImageIcon) objin.readObject();
            objin.close();
            link.close();
            this.getChatroom().getProfielForm().giveIcon(icon);
            

        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(ClientCommunication.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ClientCommunication.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void zendAvatarAanvraag(String f) {
        out.println("<?xml version=\"1.0\"?><zendAvatarAanvraag><filename>" + f + "</filename></zendAvatarAanvraag>");
    }

    public Hashtable<String, String> getSmilies() {
        return smilies;
    }

    public void setSmilies(Hashtable<String, String> smilies) {
        this.smilies = smilies;
    }

    public void topscoresBepaald(SpelScore[] scores) {
        topscoreGui.scoresBepaald(scores);
    }

    public Topscores getTopscoreGui() {
        return topscoreGui;
    }

    public void setTopscoreGui(Topscores topscoreGui) {
        this.topscoreGui = topscoreGui;
    }

    public void stuurBoggleBord(String nickname) {
        logger.info("<?xml version=\"1.0\"?><replyStuurBoggleBord><nickname>"+nickname+"</nickname>"+BoggleController.getInstance().getXMLSpelbord()+"</replyStuurBoggleBord>");
        out.println("<?xml version=\"1.0\"?><replyStuurBoggleBord><nickname>"+nickname+"</nickname>"+BoggleController.getInstance().getXMLSpelbord()+"</replyStuurBoggleBord>");
        logger.info("einde verzenden bogglebord oprichter->server");
    }

    public void zendWoorden(String nickname, String roomName, ArrayList<String> woorden) {
         if (woorden != null) {
            //logger.info(" zendGelegdeWoorden: "+woorden.size());
            String lijn = "<?xml version=\"1.0\"?><gevondenWoorden><nickname>" + nickname + "</nickname>";
            lijn += "<gameNaam>" + roomName + "</gameNaam><woordenLijst>";
            for (String sWoord : woorden) {
                lijn += "<nieuwWoord>" + sWoord + "</nieuwWoord>";
            }
            lijn += "</woordenLijst></gevondenWoorden>";
            logger.info(lijn);
            out.println(lijn);
        }
    }

    //NIEUW!
    //innerKlasse die steeds luister
    /**
     * Functie die constant blijft luisteren naar berichten van de server
     * om zo gepaste informatie in het chatvenster weer te geven.
     */
    public class AcceptMessageHandler implements Runnable {

        public void run() {
            try {
                String response;
                do {
                    response = in.readLine();
                    logger.debug("ClientCommunication: '" + response + "' ontvangen");

                    if (response.startsWith("<")) {
                        StringReader sr = new StringReader(response);
                        parser.parse(new InputSource(sr));
                    }
                } while (!response.equals("CLOSE"));
            } catch (SocketException se) {
                //fout kan optreden als server plots afgesloten wordt.
                //een 'aanvaarde' fout dus...
                if (!link.isClosed()) {
                    logger.error("Server plots afgesloten!");
                    logger.error(se.getMessage());
                }
            } catch (IOException ioe) {
                logger.error(ioe.getMessage());
            } catch (NullPointerException e) {
                logger.error("Connectie met server verbroken!");
                logger.error(e.getMessage());
                getChatroom().plaatsBericht(">> connectie met server verbroken, je berichten zullen niet meer aankomen");
                ScrabbleClient spel = getChatroom().getScrabbleGame();
                if (spel != null) {
                    spel.toonBerichtInChatVenster(">> connectie met server verbroken, je berichten zullen niet meer aankomen", true);
                }
            } catch (Exception ex) {
                logger.error("Fout tijdens AcceptMessageHandler thread!");
                logger.error(ex.getClass() + " - " + ex.getMessage());
            }
        }
    }
}
